#include "WorldManager.h"
#include "../TinyXML/tinyxml.h"
#include <math.h>
#include <string>
#include "GamePlayState.h"
#include "Enemy.h"
#include "Zone.h"
#include "Lightorb.h"
#include "../SGD Wrappers/SGD_Geometry.h"
#include <random>

WorldManager::WorldManager()
{
}


WorldManager::~WorldManager()
{

}

void WorldManager::LoadWorldSeed(std::string filePath)
{
	TiXmlDocument doc;
	doc.LoadFile(filePath.c_str());
	TiXmlElement* root = doc.RootElement();
	int numZones;
	root->Attribute("ZoneCount", &numZones);
	TiXmlElement* z = root->FirstChildElement();
	for (int i = 0; i < numZones; i++)
	{
		int xPos, yPos, radius, minPlanetRad, maxPlanetRad,
			numPlanets, enemyChance, lightChance;
		z->Attribute("X", &xPos);
		z->Attribute("Y", &yPos);
		z->Attribute("Radius", &radius);
		z->Attribute("MaxPlanetRadius", &maxPlanetRad);
		z->Attribute("MinPlanetRadius", &minPlanetRad);
		z->Attribute("NumberOfPlanets", &numPlanets);
		z->Attribute("EnemyPercentChance", &enemyChance);
		z->Attribute("LightPercentChance", &lightChance);
		Zone* newZone = new Zone;
		newZone->SetPosition({ (float)xPos, (float)yPos });
		newZone->SetSize({ radius * 2.0f, radius * 2.0f });
		newZone->CalculateRadius();
		newZone->SetMinPlanetRad(minPlanetRad);
		newZone->SetMaxPlanetRad(maxPlanetRad);
		newZone->SetNumPlanets(numPlanets);
		newZone->SetEnemyChance(enemyChance);
		newZone->SetLightChance(lightChance);
		if (i < 5)
			newZone->SetZoneType(static_cast<Zone::ZoneType>(i));
		else
			newZone->SetZoneType(Zone::ZONE5);
		if (i == 0)
			newZone->SetIsFirst(true);
		zones.push_back(newZone);
		z = z->NextSiblingElement();
	}
}

void WorldManager::PopulateZones()
{
	for (unsigned int i = 0; i < zones.size(); i++)
	{
		zones[i]->PopulatePlanets();
		if (i > 0)
			LinkZones(zones[i - 1], zones[i]);
	}
}

void WorldManager::LinkZones(Zone* z1, Zone* z2)
{
	std::random_device rd; //create the random device seed
	std::mt19937 mt(rd()); //create the random engine and seed it with the device
	std::uniform_int_distribution<int> randomOffset(-30, 30);

	SGD::Vector distance = 
		z2->GetRect().ComputeCenter() - z1->GetRect().ComputeCenter();
	float length = distance.ComputeLength();
	distance.Normalize();
	for (int i = 0; i < length; i += 200)
	{
		Planets* newP = new Planets;
		newP->SetSize({ 46, 46 });
		newP->CalculateRadius();
		int xOffset = randomOffset(mt);
		int yOffset = randomOffset(mt);
		newP->SetPosition({ z1->GetRect().ComputeCenter().x + distance.x * i + xOffset,
			z1->GetRect().ComputeCenter().y + distance.y * i + yOffset});
		SGD::Vector to1 = z1->GetRect().ComputeCenter() - newP->GetPosition();
		float d1 = to1.ComputeLength();
		SGD::Vector to2 = z2->GetRect().ComputeCenter() - newP->GetPosition();
		float d2 = to2.ComputeLength();
		if (d1 > z1->GetRadius() + newP->GetRadius()
			&& d2 > z2->GetRadius() + newP->GetRadius())
			z2->AddAsteroid(newP);
		else
			delete newP;
	}
}

void WorldManager::ReleaseZones()
{
	for (unsigned int i = 0; i < zones.size(); i++)
	{
		zones[i]->ReleasePlanets();
		zones[i]->Release();
	}
	zones.clear();
}